package com.tticar.invmanager.service.impl;

import com.baomidou.mybatisplus.entity.Columns;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.tticar.invmanager.common.Enum.CodeType;
import com.tticar.invmanager.common.exception.MyServiceException;
import com.tticar.invmanager.common.shiro.MySecurityUtils;
import com.tticar.invmanager.common.utils.DateUtils;
import com.tticar.invmanager.common.utils.date.DateStyle;
import com.tticar.invmanager.common.utils.date.DateUtil;
import com.tticar.invmanager.entity.*;
import com.tticar.invmanager.entity.vo.BybsDetailDto;
import com.tticar.invmanager.entity.vo.BybsDto;
import com.tticar.invmanager.entity.vo.MyPage;
import com.tticar.invmanager.mapper.BybsMapper;
import com.tticar.invmanager.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author joeyYan
 * @since 2018-10-18
 */
@Service
public class BybsServiceImpl extends ServiceImpl<BybsMapper, Bybs> implements IBybsService {

    @Autowired
    private ICodeCounterService codeCounterService;

    @Autowired
    private IBybsDetailService bybsDetailService;

    @Autowired
    private IRepositoryCountService repositoryCountService;

    @Autowired
    private IInRepositoryDetailService repositoryDetailService;

    @Autowired
    private IOutRepositoryDetailService outRepositoryDetailService;

    @Autowired
    private IInRepositoryDetailService inRepositoryDetailService;

    @Autowired
    private IMMaterielSkuService materielSkuService;

    @Autowired
    private IWPositionMaterielService positionMaterielService;
    
    @Override
    public Page selectPage(Bybs bybs, MyPage<Bybs> page) {
        Wrapper wrapper = new EntityWrapper();
        //wrapper.like(Strings.isNotEmpty(bybs.getName()), Bybs.NAME, bybs.getName());
        Columns columns = Columns.create().column("*")
                .column("(select t.name from w_wearhouse t where t.id=wearhouse_id)", "houseName");
        wrapper.setSqlSelect(columns);
        wrapper.ne("status", -1);
        wrapper.ge(bybs.getStartTime() != null, Bybs.ORDER_TIME, bybs.getStartTime());
        wrapper.le(bybs.getEndTime() != null, Bybs.ORDER_TIME, DateUtils.getInstance().getDateEndTime(bybs.getEndTime()));
        wrapper.eq(bybs.getWearhouseId() != null, Bybs.WEARHOUSE_ID, bybs.getWearhouseId());
        wrapper.eq(bybs.getOrderType() != null, Bybs.ORDER_TYPE, bybs.getOrderType());
        wrapper.eq(bybs.getStatus() != null, Bybs.STATUS, bybs.getStatus());
        wrapper.orderBy("order_time", false);
        return this.selectMapsPage(page, wrapper);
    }
    @Override
    public void delete(List<Long> ids) {
        List list = new ArrayList();
        for (Long id : ids) {
            Bybs bybs = new Bybs();
            bybs.setId(id);
            bybs.setStatus(-1);
            list.add(bybs);
        }
        this.updateBatchById(list);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addBybs(BybsDto dto) {
        List<BybsDetailDto> goodsToList = dto.getList();

        Bybs bybs = new Bybs();
        Date now = DateUtil.StringToDate(dto.getOrderTime() + " " + DateUtil.DateToString(new Date(), DateStyle.HH_MM_SS));
        bybs.setOrderType(dto.getOrderType());
        bybs.setOrderTime(now);
        bybs.setCode(codeCounterService.getOrderCode(dto.getOrderType() == 0 ? CodeType.BY : CodeType.BS));
        bybs.setWearhouseId(dto.getHouseId());
        bybs.setRemark(dto.getRemark());
        bybs.setCtime(now);
        bybs.setCname(MySecurityUtils.currentUser().getUsername());
        this.baseMapper.insert(bybs);

        Integer totalNum = 0;
        BigDecimal totalFee = BigDecimal.ZERO;
        for(BybsDetailDto tmp : goodsToList) {
            BybsDetail detail = new BybsDetail();
            detail.setBybsId(bybs.getId());
            detail.setWearhouseId(bybs.getWearhouseId());
            detail.setPositionId(tmp.getPositionId());
            detail.setBatchNumber(tmp.getHouse());
            detail.setSkuId(tmp.getSkuId());
            detail.setNum(tmp.getNum());
            detail.setPrice(tmp.getPrice());
            detail.setFee(tmp.getFee());
            this.bybsDetailService.insert(detail);

            totalNum += detail.getNum();
            if (detail.getFee() != null) {
                totalFee = totalFee.add(detail.getFee());
            }

        }

        bybs.setNum(totalNum);
        bybs.setFee(totalFee);
        this.baseMapper.updateById(bybs);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void editBybs(BybsDto dto) {
        List<BybsDetailDto> goodsToList = dto.getList();

        Bybs bybs = this.baseMapper.selectById(dto.getId());
        bybs.setRemark(dto.getRemark());

        Integer totalNum = 0;
        BigDecimal totalFee = BigDecimal.ZERO;
        for(BybsDetailDto tmp : goodsToList) {
            BybsDetail detail = this.bybsDetailService.selectById(tmp.getId());
            detail.setPositionId(tmp.getPositionId());
            detail.setBatchNumber(tmp.getHouse());
            detail.setNum(tmp.getNum());
            detail.setPrice(tmp.getPrice());
            detail.setFee(tmp.getFee());
            detail.setRemark(tmp.getRemark());
            this.bybsDetailService.updateById(detail);

            totalNum += detail.getNum();
            totalFee = totalFee.add(detail.getFee());
        }

        bybs.setNum(totalNum);
        bybs.setFee(totalFee);
        this.baseMapper.updateById(bybs);

        if(dto.getType() == 1) {//审核
            audit(dto.getId());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void audit(Long id) {
        Bybs bybs = this.baseMapper.selectById(id);

        bybs.setOname(MySecurityUtils.currentUser().getUsername());
        bybs.setOtime(new Date());
        bybs.setStatus(1);
        this.baseMapper.updateById(bybs);

        List<BybsDetail> list = this.bybsDetailService.selectList(new EntityWrapper().eq("bybs_id", id));
        if(bybs.getOrderType() == 0) {//报溢
            String rkCode = codeCounterService.getOrderCode(CodeType.RK);
            for(BybsDetail detail : list) {
                //入库校验 当前仓库是否仍绑定了此商品
                MMaterielSku sku = this.materielSkuService.selectById(detail.getSkuId());
                int isExsit = this.positionMaterielService.selectCount(new EntityWrapper().eq("materiel_id", sku.getMid()).eq("position_id", detail.getPositionId()));
                if(isExsit == 0) {
                    throw new MyServiceException(sku.getCode() + "库位无效，请重新选择");
                }

                //生成入库单
                InRepositoryDetail inDetail = new InRepositoryDetail();
                inDetail.setSkuId(detail.getSkuId());
                inDetail.setCode(rkCode);
                inDetail.setBuszId(detail.getId());
                inDetail.setBatchNumber(codeCounterService.getBatchCode());
                inDetail.setWearhouseId(detail.getWearhouseId());
                inDetail.setPositionId(detail.getPositionId());
                inDetail.setOrderTime(bybs.getOrderTime());
                inDetail.setType(3);//报溢入库
                inDetail.setCount(detail.getNum());
                inDetail.setStatus(0);
                inDetail.setCtime(new Date());
                inDetail.setUsername(MySecurityUtils.currentUser().getUsername());
                inRepositoryDetailService.insertOrUpdate(inDetail);

                repositoryCountService.updateRepositoryCount(detail.getSkuId(), inDetail.getWearhouseId(), inDetail.getCount());
            }
        } else {
            for(BybsDetail detail : list) {
                String house = detail.getBatchNumber();
                Integer count = detail.getNum();
                List<RepositoryCount> repositoryCounts = repositoryCountService.queryOutRepository(detail.getSkuId());
                if (repositoryCounts != null && repositoryCounts.size() > 0) {
                    for (RepositoryCount rep : repositoryCounts) {


                        Long wearhouseId = rep.getWearhouseId();

                        Integer num = Integer.valueOf(rep.getCount() > count ? count : rep.getCount());

                        OutRepositoryDetail outDetail = new OutRepositoryDetail();
                        outDetail.setSkuId(detail.getSkuId());
                        outDetail.setCode(codeCounterService.getOrderCode(CodeType.CK));
                        outDetail.setBuszId(detail.getId());

                        outDetail.setWearhouseId(bybs.getWearhouseId());

                        outDetail.setOrderTime(bybs.getOrderTime());
                        outDetail.setType(3);//报损出库
                        outDetail.setCount(num);
                        outDetail.setRemark(detail.getRemark());
                        outDetail.setStatus(0);
                        outDetail.setCtime(new Date());
                        outDetail.setUsername(MySecurityUtils.currentUser().getUsername());
                        this.outRepositoryDetailService.insert(outDetail);

                        repositoryCountService.updateRepositoryCount(detail.getSkuId(), wearhouseId, num * -1);

                        count = count - rep.getCount();
                        if (count <= 0) {
                            break;
                        }

                    }
                } else {
                    throw new MyServiceException("库存不足");
                }
//                for(String tmp : house.split(",")) {
//                    String[] arr = tmp.split("_");
//                    Long positionId = Long.valueOf(arr[2]);
//                    String batchCode = arr[4];
//                    Integer num = Integer.valueOf(arr[6]);
//
//                    Long nowNum = this.repositoryDetailService.getSkuNumByBatchCode(detail.getSkuId(), batchCode);
//                    if(nowNum < num) {
//                        throw new MyServiceException("库位无效，请重新选择库存");
//                    }
//
//                    //生成出库单
//                    OutRepositoryDetail outDetail = new OutRepositoryDetail();
//                    outDetail.setSkuId(detail.getSkuId());
//                    outDetail.setCode(codeCounterService.getOrderCode(CodeType.CK));
//                    outDetail.setBuszId(detail.getId());
//                    outDetail.setBatchNumber(batchCode);
//                    outDetail.setWearhouseId(bybs.getWearhouseId());
//                    outDetail.setPositionId(positionId);
//                    outDetail.setOrderTime(bybs.getOrderTime());
//                    outDetail.setType(3);//报损出库
//                    outDetail.setCount(num);
//                    outDetail.setRemark(detail.getRemark());
//                    outDetail.setStatus(0);
//                    outDetail.setCtime(new Date());
//                    outDetail.setUsername(MySecurityUtils.currentUser().getUsername());
//                    this.outRepositoryDetailService.insert(outDetail);
//
//                    repositoryCountService.updateRepositoryCountByPositionId(outDetail.getSkuId(), outDetail.getWearhouseId(), outDetail.getPositionId(), outDetail.getCount() * -1);
//                }
            }
        }
    }
}
